package com.linkgie.galaxyframework.binaryserialize.impl;

import com.linkgie.galaxyframework.binaryserialize.BinarySpecification;
import com.linkgie.galaxyframework.binaryserialize.EnumSpecification;
import com.linkgie.galaxyframework.binaryserialize.FieldSpecification;
import com.linkgie.galaxyframework.binaryserialize.NumberEncoding;
import com.linkgie.galaxyframework.binaryserialize.PrimitiveType;
import com.linkgie.galaxyframework.utils.TextEncoding;

/**
 * 字段格式描述；
 * 
 * @author huanghaiquan
 *
 */
class FieldSpecDescription implements FieldSpecification {

	private BinaryTypeVersionContext contractContext;

	private int order;

	private String name;

	private String description;

	private boolean iterable;

	private PrimitiveType primitiveType;

	private TextEncoding textEncoding;

	private NumberEncoding numberEncoding;

	private EnumSpecification enumType;

	private int maxSize;

	private Class<?> sourceClass;

	private boolean abstracted = false;


	/**
	 * 创建一个二进制原生类型的字段格式描述；
	 * 
	 * @param order
	 * @param name
	 * @param decription
	 * @param primitiveType
	 * @param numberEncoding
	 * @param iterable
	 * @param maxSize
	 * @param sourcePrimitiveClass
	 */
	public FieldSpecDescription(int order, String name, String decription, PrimitiveType primitiveType, TextEncoding textEncoding,
			NumberEncoding numberEncoding, boolean iterable, int maxSize, Class<?> sourcePrimitiveClass) {
		if (primitiveType == null) {
			throw new IllegalArgumentException("primitiveType is null!");
		}
		this.order = order;
		this.name = name;
		this.description = decription;
		this.primitiveType = primitiveType;
		this.textEncoding = textEncoding;
		this.numberEncoding = numberEncoding;
		this.iterable = iterable;
		this.maxSize = maxSize;
		this.sourceClass = sourcePrimitiveClass;
	}

	/**
	 * 创建一个二进制枚举类型的字段格式描述；
	 * 
	 * @param order
	 * @param name
	 * @param decription
	 * @param enumType
	 * @param repeatable
	 * @param sourceEnumClass
	 */
	public FieldSpecDescription(int order, String name, String decription, EnumSpecification enumType,
			boolean repeatable, Class<?> sourceEnumClass) {
		if (enumType == null) {
			throw new IllegalArgumentException("enum specification is null!");
		}
		this.order = order;
		this.name = name;
		this.description = decription;
		this.enumType = enumType;
		this.iterable = repeatable;
		this.maxSize = -1;
		this.sourceClass = sourceEnumClass;
	}

	/**
	 * 创建一个二进制对象类型的字段格式描述；
	 * 
	 * @param order
	 * @param name
	 * @param decription
	 * @param binaryType
	 * @param abstracted
	 * @param iterable
	 * @param sourceClass
	 */
	public FieldSpecDescription(int order, String name, String decription, BinaryTypeVersionContext contractContext,
			boolean abstracted, boolean iterable) {
		if (contractContext == null) {
			throw new IllegalArgumentException("contractType is null!");
		}
		this.contractContext = contractContext;
		
		this.order = order;
		this.name = name;
		this.description = decription;
		this.iterable = iterable;
		this.maxSize = -1;
		this.abstracted = abstracted;
		this.sourceClass = contractContext.sourceClass;
	}

	/**
	 * @return the contractContext
	 */
	public BinaryTypeVersionContext getContractContext() {
		return contractContext;
	}

	@Override
	public PrimitiveType getPrimitiveType() {
		return primitiveType;
	}

	@Override
	public TextEncoding getTextEncoding() {
		return textEncoding;
	}

	@Override
	public NumberEncoding getNumberEncoding() {
		return numberEncoding;
	}

	@Override
	public EnumSpecification getEnumType() {
		return enumType;
	}

	@Override
	public BinarySpecification getBinaryType() {
		return contractContext.codec.get().getSpecification();
	}

	@Override
	public boolean isIterable() {
		return iterable;
	}

	@Override
	public int getMaxSize() {
		return maxSize;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public String getDescription() {
		return description;
	}

	@Override
	public boolean isAbstracted() {
		return abstracted;
	}

	public int getOrder() {
		return order;
	}

	public Class<?> getSourceClass() {
		return sourceClass;
	}

	@Override
	public boolean isPrimitiveField() {
		return this.primitiveType != null;
	}

	@Override
	public boolean isEnumField() {
		return this.enumType != null;
	}

	@Override
	public boolean isContractField() {
		return this.contractContext != null;
	}

}
